home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Mac Power 2002 February
/
MACPOWER-2002-02.ISO.7z
/
MACPOWER-2002-02.ISO
/
MacPowerオリジナル⁄連載
/
P.260⁄ぷろれぼX
/
VJ Core.c
< prev
next >
Wrap
C/C++ Source or Header
|
2001-11-03
|
24KB
|
747 lines
//---------------------------------------------------------------------
//
// VJ システム コアプログラム
//
//---------------------------------------------------------------------
#include <Carbon.h>
#include "VJ Core.h"
//---------------------------------------------------------------------
//ウィンドウ表示ポート(どこからも参照できるようにグローバル定義)
//---------------------------------------------------------------------
WindowRef mainWindow;
DialogRef ctrlDialog;
//---------------------------------------------------------------------
//読み込んだPICTリソース情報
//---------------------------------------------------------------------
PicHandle bgPictData;
PicHandle previewA_PicData;
PicHandle previewB_PicData;
//---------------------------------------------------------------------
//3つのオフスクリーン用情報
//---------------------------------------------------------------------
//作成・破棄時に使用、オフスクリーン全体を指す
GWorldPtr previewA_GWorld;
GWorldPtr previewB_GWorld;
GWorldPtr previewC_GWorld;
//イメージデータそのものの先頭位置を指す
Ptr previewA_BaseAddr;
Ptr previewB_BaseAddr;
Ptr previewC_BaseAddr;
//イメージデータそのものの横幅を指す
long previewA_RowBytes;
long previewB_RowBytes;
long previewC_RowBytes;
//---------------------------------------------------------------------
//動 作フ ラ グ用(現 在 は、A->B効 果中にfalse、B->A効 果 中にtrue)
Boolean timerFlip = false;
Boolean switchView = true;
//第6回 「スクロール効果による画像切り替え」(RollImage関数使用)用パラメータ
//スクロール水平位置
short rollImageOffset = CENTER_PREVIEW_H;
//スクロール速度(必ずCENTER_PREVIEW_Hの約数で)
#define ROLLSPEED 8
//左右の画像の合成度
short mixLevel = 10;
//変化速度
#define MIXSPEED 10
//エフェクトの種類
short effectNo = 0;
//---------------------------------------------------------------------
//
// プログラムメイン(ここからスタート)
//
//---------------------------------------------------------------------
void main()
{
Rect bounds = { 0, 0, SCREEN_SIZE_V, SCREEN_SIZE_H };
Rect screenRect;
OSStatus err;
EventHandlerUPP myWinEvtHandler;
EventHandlerRef ref;
EventTypeSpec list[] = { {kEventClassWindow, kEventWindowClose },
{ kEventClassWindow, kEventWindowDrawContent } ,
{ kEventClassMouse , kEventMouseDown } ,
{ kEventClassKeyboard , kEventRawKeyDown } };
EventLoopTimerRef loopTimerRef;
//イメージの詳細情報が格納されたデータ位置を指す
PixMapHandle previewA_PixMap;
PixMapHandle previewB_PixMap;
PixMapHandle previewC_PixMap;
//カーソルの初期化
InitCursor();
//メニューの組み込み
err = InstallStandardMenuBar();
if (err != noErr) ExitToShell();
//アップルイベントの組み込み
err = AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, NewAEEventHandlerUPP(QuitAppleEventHandler), 0, FALSE);
if (err != noErr) ExitToShell();
//アプリケーションイベントハンドラーの組み込み
InstallAppEvents();
//画像の読み込み
LoadPictures();
//ウィンドウの作成
err = CreateNewWindow(kDocumentWindowClass,
kWindowCloseBoxAttribute | kWindowStandardHandlerAttribute,
&bounds, &mainWindow);
if (err != noErr) ExitToShell();
//表示画面を取得
GetWindowGreatestAreaDevice(mainWindow,NULL,NULL,&screenRect);
//3つのオフスクリーンを作成し各種情報を取得する
previewA_GWorld = CreateOffscreen(VJPICT_SIZE_H,VJPICT_SIZE_V);
previewA_PixMap = GetGWorldPixMap(previewA_GWorld);
previewA_BaseAddr = GetPixBaseAddr(previewA_PixMap);
previewA_RowBytes = GetPixRowBytes(previewA_PixMap);
previewB_GWorld = CreateOffscreen(VJPICT_SIZE_H,VJPICT_SIZE_V);
previewB_PixMap = GetGWorldPixMap(previewB_GWorld);
previewB_BaseAddr = GetPixBaseAddr(previewB_PixMap);
previewB_RowBytes = GetPixRowBytes(previewB_PixMap);
previewC_GWorld = CreateOffscreen(VJPICT_SIZE_H,VJPICT_SIZE_V);
previewC_PixMap = GetGWorldPixMap(previewC_GWorld);
previewC_BaseAddr = GetPixBaseAddr(previewC_PixMap);
previewC_RowBytes = GetPixRowBytes(previewC_PixMap);
//各オフスクリーンを白で初期化
FillImage(previewA_BaseAddr,previewA_RowBytes,VJPICT_SIZE_H,VJPICT_SIZE_V,0x00ffffff);
FillImage(previewB_BaseAddr,previewB_RowBytes,VJPICT_SIZE_H,VJPICT_SIZE_V,0x00ffffff);
FillImage(previewC_BaseAddr,previewC_RowBytes,VJPICT_SIZE_H,VJPICT_SIZE_V,0x00ffffff);
//イベントハンドラの取得
myWinEvtHandler = NewEventHandlerUPP(MyWindowEventHandler);
//イベントハンドラの組み込み
InstallWindowEventHandler(mainWindow, myWinEvtHandler, 4 , list, 0, &ref);
//ループタイマーの起動
InstallEventLoopTimer(GetCurrentEventLoop(),0,0.05,NewEventLoopTimerUPP(MyTimerRoutine),NULL,&loopTimerRef);
//ウィンドウを画面中央に配置
MoveWindowStructure(mainWindow,(screenRect.right-screenRect.left)/2-SCREEN_SIZE_H/2,(screenRect.bottom-screenRect.top)/2-SCREEN_SIZE_V/2);
//ウィンドウを表示
ShowWindow(mainWindow);
//イベントループの開始
RunApplicationEventLoop();
//イベントハンドラを閉じる
DisposeEventHandlerUPP(myWinEvtHandler);
//3つのオフスクリーンを破棄する
DisposeGWorld(previewA_GWorld);
DisposeGWorld(previewB_GWorld);
DisposeGWorld(previewC_GWorld);
}
//---------------------------------------------------------------------
//
// ウィンドウのイベントハンドラー処理
//
//---------------------------------------------------------------------
pascal OSStatus
MyWindowEventHandler(EventHandlerCallRef myHandler, EventRef event, void* userData)
{
#pragma unused (myHandler, userData)
WindowRef window;
OSStatus result = eventNotHandledErr;
Rect buttonBounds = { 341 , 234, 381, 404 };
Point mousePt;
MouseTrackingResult mouseRes;
UInt32 keyCode = 0;
GetEventParameter(event, kEventParamDirectObject, typeWindowRef, NULL, sizeof(window), NULL, &window);
switch(GetEventClass(event))
{
//ウィンドウイベント
case kEventClassWindow:
switch(GetEventKind(event))
{
case kEventWindowDrawContent:
HandleWindowUpdate(window);
result = noErr;
break;
case kEventWindowClose:
DisposeWindow(window);
QuitApplicationEventLoop();
result = noErr;
break;
}
break;
//マウスイベント
case kEventClassMouse:
switch(GetEventKind(event))
{
case kEventMouseDown:
TrackMouseLocation(GetWindowPort(mainWindow),&mousePt,&mouseRes);
if (PtInRect(mousePt,&buttonBounds) == true) {
switchView = true;
}
break;
}
break;
//キーボードイベント
case kEventClassKeyboard:
switch(GetEventKind(event))
{
case kEventRawKeyDown:
//キ ー コー ドを取 得
GetEventParameter(event, kEventParamKeyCode, typeUInt32, NULL, sizeof(UInt32), NULL, &keyCode);
//ス ペ ースキ ー が押 さ れたかど う かを判 断
if (keyCode == 49) {
switchView = true;
}
break;
}
break;
}
return result;
}
//---------------------------------------------------------------------
//
// 一定間隔ごとに呼び出されるタイマー処理
//
//---------------------------------------------------------------------
pascal void MyTimerRoutine(EventLoopTimerRef loopTimerRef,void* userRef)
{
#pragma unused (loopTimerRef, userRef)
if (switchView == true) {
if (timerFlip == false) {
MixImage(previewA_BaseAddr,previewA_RowBytes,
previewB_BaseAddr,previewB_RowBytes,
previewC_BaseAddr,previewC_RowBytes,
VJPICT_SIZE_H,VJPICT_SIZE_V,mixLevel);
//次のスクロール表示位置を計算
mixLevel -= MIXSPEED;
//スクロールが左まで達したら、次のスクロール処理へ
if (mixLevel < 0) {
timerFlip = true;
switchView = false;
mixLevel = 100;
}
//effectNoが0以外ならトーンエフェクト
if (effectNo != 0) DoEffects(previewC_BaseAddr,previewC_RowBytes,VJPICT_SIZE_H,VJPICT_SIZE_V,effectNo);
} else {
MixImage(previewA_BaseAddr,previewA_RowBytes,
previewB_BaseAddr,previewB_RowBytes,
previewC_BaseAddr,previewC_RowBytes,
VJPICT_SIZE_H,VJPICT_SIZE_V,100 - mixLevel);
//次のスクロール表示位置を計算
mixLevel -= MIXSPEED;
//スクロールが左まで達したら、次のスクロール処理へ
if (mixLevel < 0) {
timerFlip = false;
switchView = false;
mixLevel = 100;
}
//effectNoが0以外ならトーンエフェクト
if (effectNo != 0) DoEffects(previewC_BaseAddr,previewC_RowBytes,VJPICT_SIZE_H,VJPICT_SIZE_V,effectNo);
}
}
//オフスクリーンCをウィンドウに表示
CopyToWindow(previewC_GWorld,mainWindow);
}
//---------------------------------------------------------------------
//
// ウィンドウの更新
//
//---------------------------------------------------------------------
void HandleWindowUpdate(WindowRef window)
{
DrawBackground(window);
}
//---------------------------------------------------------------------
//
// メニューの組み込み
//
//---------------------------------------------------------------------
OSStatus InstallStandardMenuBar(void)
{
Handle menuBar;
MenuRef menu;
long response;
OSStatus err = noErr;
menuBar = GetNewMBar(128);
if (menuBar)
{
SetMenuBar(menuBar);
//MacOS X上ならFileメニューからQuitを取り除く
err = Gestalt(gestaltMenuMgrAttr, &response);
if ((err == noErr) && (response & gestaltMenuMgrAquaLayoutMask))
{
menu = GetMenuHandle(mFile);
DeleteMenuItem(menu, iQuit);
}
DrawMenuBar();
}
return err;
}
//---------------------------------------------------------------------
//
// 終了時のイベントハンドラー
//
//---------------------------------------------------------------------
pascal OSErr QuitAppleEventHandler(const AppleEvent* appleEvt, AppleEvent* reply, long refcon)
{
#pragma unused (appleEvt, reply, refcon)
QuitApplicationEventLoop();
return noErr;
}
//---------------------------------------------------------------------
//
// アプリケーションイベントハンドラーの組み込み
//
//---------------------------------------------------------------------
void InstallAppEvents(void)
{
EventHandlerUPP gAppCommandProcess;
EventTypeSpec eventType;
gAppCommandProcess = NewEventHandlerUPP(DoAppCommandProcess);
eventType.eventClass = kEventClassCommand;
eventType.eventKind = kEventCommandProcess;
InstallApplicationEventHandler(gAppCommandProcess, 1, &eventType, NULL, NULL);
}
//---------------------------------------------------------------------
//
// アプリケーションイベントハンドラー
//
//---------------------------------------------------------------------
pascal OSStatus DoAppCommandProcess(EventHandlerCallRef nextHandler, EventRef theEvent, void* userData)
{
#pragma unused (nextHandler, userData)
HICommand aCommand;
OSStatus result;
GetEventParameter(theEvent, kEventParamDirectObject, typeHICommand, NULL, sizeof(HICommand), NULL, &aCommand);
switch (aCommand.commandID)
{
case 'eff0':
effectNo = 0;
result = noErr;
break;
case 'eff1':
effectNo = 1;
result = noErr;
break;
case 'eff2':
effectNo = 2;
result = noErr;
break;
case 'eff3':
effectNo = 3;
result = noErr;
break;
case kHICommandQuit:
QuitApplicationEventLoop();
result = noErr;
break;
default:
result = eventNotHandledErr;
break;
}
HiliteMenu(0);
return result;
}
//---------------------------------------------------------------------
//
// 画像データの読み込み
//
//---------------------------------------------------------------------
void LoadPictures(void)
{
//背景の読み込み
bgPictData = GetPicture ( BG_PICT_ID );
//プレビューAの読み込み
previewA_PicData = GetPicture ( PREVIEW_A );
//プレビューBの読み込み
previewB_PicData = GetPicture ( PREVIEW_B );
}
//---------------------------------------------------------------------
//
// 背景など固定部分の描画
//
//---------------------------------------------------------------------
void DrawBackground(WindowRef window)
{
GrafPtr savePort;
CQDProcsPtr saveProcs;
//表示領域の指定 { 左上Y,左上X,右下Y,右下X } (Y,X という順番に注意)
Rect bgBounds = { 0, 0, SCREEN_SIZE_V, SCREEN_SIZE_H };
Rect previewAbounds = { PREVIEW_A_PREVIEW_Y , PREVIEW_A_PREVIEW_X,
PREVIEW_A_PREVIEW_Y + SIDE_PREVIEW_V, PREVIEW_A_PREVIEW_X + SIDE_PREVIEW_H };
Rect previewBbounds = { PREVIEW_B_PREVIEW_Y , PREVIEW_B_PREVIEW_X,
PREVIEW_B_PREVIEW_Y + SIDE_PREVIEW_V, PREVIEW_B_PREVIEW_X + SIDE_PREVIEW_H };
//現在の描画対象情報を保存
GetPort(&savePort);
saveProcs = GetPortGrafProcs(savePort);
//描画対象ポートをウィンドウに設定
SetPortWindowPort(window);
//ウィンドウに描画
DrawPicture (bgPictData,&bgBounds);
DrawPicture (previewA_PicData,&previewAbounds);
DrawPicture (previewB_PicData,&previewBbounds);
//描画先の矩形領域を再設定
SetRect(&bgBounds,0,0,VJPICT_SIZE_H,VJPICT_SIZE_V);
//描画対象ポートをオフスクリーンAに設定
SetPort(previewA_GWorld);
//オフスクリーンAに描画
DrawPicture (previewA_PicData,&bgBounds);
//描画対象ポートをオフスクリーンBに設定
SetPort(previewB_GWorld);
//オフスクリーンBに描画
DrawPicture (previewB_PicData,&bgBounds);
//現在の描画対象情報を復帰
SetPortGrafProcs(savePort, saveProcs);
}
//---------------------------------------------------------------------
//
// オフクリーン(GWorld)の作成
//
// 引数: sizeX オフスクリーンの横サイズ
// sizeY オフスクリーンの縦サイズ
//
// 戻り値: 作成したGWorldのGWorldPtr型データ
//---------------------------------------------------------------------
GWorldPtr CreateOffscreen(short sizeX,short sizeY)
{
CGrafPtr retPtr = nil;
Rect screenSize;
SetRect(&screenSize,0,0,sizeX,sizeY);
NewGWorld(&retPtr, 32, &screenSize, nil, nil, 0);
LockPixels(GetGWorldPixMap(retPtr));
return retPtr;
}
//---------------------------------------------------------------------
//
// 指定したイメージデータをfillPixelで埋める
//
// 引数: Ptr ベースアドレス(ポインタ)
// long ローバイト
// short イメージのサイズ横幅
// short イメージのサイズ縦幅
// unsigned long 埋めるピクセルデータ
//
// 戻り値: なし
//---------------------------------------------------------------------
void FillImage(Ptr baseAddress,long rowBytes,short imageSizeX,short imageSizeY,unsigned long fillPixel)
{
Ptr writingAddress; //ピクセルデータを書き込み中のポインタ
short loopX,loopY; //forループ用
//下方向へのループを設定
for (loopY = 0 ; loopY != imageSizeY ; loopY++) {
//各ラインの始点を指すポインタを取得し設定
writingAddress = baseAddress + rowBytes * loopY;
//右方向に1ライン分のループを設定
for (loopX = 0 ; loopX != imageSizeX ; loopX++) {
//ポインタを4バイト(unsigned long型)ずつ進めながら書き込んでいく
*((unsigned long*)writingAddress)++ = fillPixel;
}
}
}
//---------------------------------------------------------------------
//
// 指定したGWorldの内容をウィンドウ(中央プレビュー部)に描画
//
// 引数: GWorldPtr 転送元オフスクリーン
// WindowRef 転送先ウィンドウ(表示座標はプレビューC部分)
// 戻り値: なし
//---------------------------------------------------------------------
void CopyToWindow(GWorldPtr srcGWorld,WindowRef dstWindow)
{
GrafPtr savePort;
CQDProcsPtr saveProcs;
Rect srcRect,dstRect;
//現在の描画対象情報を保存
GetPort(&savePort);
saveProcs = GetPortGrafProcs(savePort);
//転送元のRectを設定
SetRect(&srcRect,0,0,VJPICT_SIZE_H,VJPICT_SIZE_V);
//転送先(ウィンドウ上の表示位置)のRectを設定
SetRect(&dstRect,PREVIEW_C_PREVIEW_X,PREVIEW_C_PREVIEW_Y,
PREVIEW_C_PREVIEW_X + CENTER_PREVIEW_H,PREVIEW_C_PREVIEW_Y + CENTER_PREVIEW_V);
//描画対象ポートの設定
SetPortWindowPort(dstWindow);
//指定したオフスクリーンの指定範囲をウィンドウに転送して表示
CopyBits(GetPortBitMapForCopyBits(srcGWorld), GetPortBitMapForCopyBits(GetWindowPort(dstWindow)),&srcRect,&dstRect,srcCopy,nil);
//現在の描画対象情報を復帰
SetPortGrafProcs(savePort, saveProcs);
}
//---------------------------------------------------------------------
//
// 指定した2つのイメージデータをコピー
//
// 引数: Ptr srcBaseAddress 転送元ベースアドレス(ポインタ)
// long srcRowBytes 転送元ローバイト
// Ptr dstBaseAddress 転送先ベースアドレス(ポインタ)
// long dstRowBytes 転送先ローバイト
// short imageSizeX イメージのサイズ横幅
// short imageSizeY イメージのサイズ縦幅
//
// 戻り値: なし
//---------------------------------------------------------------------
void CopyImage(Ptr srcBaseAddress,long srcRowBytes,Ptr dstBaseAddress,long dstRowBytes,short imageSizeX,short imageSizeY)
{
Ptr readAddress; //ピクセルデータを読み込み中のポインタ(転送元)
Ptr writingAddress; //ピクセルデータを書き込み中のポインタ(転送先)
short loopX,loopY; //forループ用
//下方向へのループを設定
for (loopY = 0 ; loopY != imageSizeY ; loopY++) {
//各ラインの始点を指すポインタを取得し設定
readAddress = srcBaseAddress + srcRowBytes * loopY;
writingAddress = dstBaseAddress + dstRowBytes * loopY;
//右方向に1ライン分のループを設定
for (loopX = 0 ; loopX != imageSizeX ; loopX++) {
//ポインタを4バイト(unsigned long型)ずつ進めながら書き込んでいく
*((unsigned long*)writingAddress)++ = *((unsigned long*)readAddress)++;
}
}
}
//---------------------------------------------------------------------
//
// イメージデータを指 定し たX座標からコピー
//
// 引数: Ptr srcBaseAddress 転送元ベースアドレス(ポインタ)
// long srcRowBytes 転送元ローバイト
// Ptr dstBaseAddress 転送先ベースアドレス(ポインタ)
// long dstRowBytes 転送先ローバイト
// short imageSizeX イメージのサイズ横幅
// short imageSizeY イメージのサイズ縦幅
// short offsetX 転 送先を張 り 付け るX座 標
//
// 戻り値: なし
//---------------------------------------------------------------------
void RollImage(Ptr srcBaseAddress,long srcRowBytes,Ptr dstBaseAddress,long dstRowBytes,short imageSizeX,short imageSizeY,short offsetX)
{
Ptr readAddress; //ピクセルデータを読み込み中のポインタ(転送元)
Ptr writingAddress; //ピクセルデータを書き込み中のポインタ(転送先)
short loopX,loopY; //forループ用
//下方向へのループを設定
for (loopY = 0 ; loopY != imageSizeY ; loopY++) {
//各ラインの始点を指すポインタを取得し設定
readAddress = srcBaseAddress + srcRowBytes * loopY;
writingAddress = dstBaseAddress + dstRowBytes * loopY
+ offsetX * sizeof(unsigned long);
//右方向に1ライン分のループを設定
for (loopX = 0 ; loopX != imageSizeX - offsetX ; loopX++) {
//ポインタか ら4バイト(unsigned long型)ずつ書き込んでいく
*((unsigned long*)writingAddress)++ = *((unsigned long*)readAddress)++;
}
}
}
//---------------------------------------------------------------------
//
// 2つのイメージデータを指定した度合いで合成
//
// 引数: Ptr srcBaseAddress1 転送元ベースアドレス1(ポインタ)
// long srcRowBytes1 転送元ローバイト1
// Ptr srcBaseAddress2 転送元ベースアドレス2(ポインタ)
// long srcRowBytes2 転送元ローバイト2
// Ptr dstBaseAddress 転送先ベースアドレス(ポインタ)
// long dstRowBytes 転送先ローバイト
// short imageSizeX イメージのサイズ横幅
// short imageSizeY イメージのサイズ縦幅
// short fadeLevel 転送元1の合成の割合(0〜100%)
//
// 戻り値: なし
//---------------------------------------------------------------------
void MixImage(Ptr srcBaseAddress1,long srcRowBytes1,
Ptr srcBaseAddress2,long srcRowBytes2,
Ptr dstBaseAddress,long dstRowBytes,
short imageSizeX,short imageSizeY,short fadeLevel)
{
Ptr readAddress1; //ピクセルデータを読み込み中のポインタ(転送元1)
Ptr readAddress2; //ピクセルデータを読み込み中のポインタ(転送元2)
Ptr writingAddress; //ピクセルデータを書き込み中のポインタ(転送先)
short loopX,loopY; //forループ用
//転送元1か ら読 み 込ん だピ ク セル情 報
unsigned long readPixel1;
unsigned long red1;
unsigned long green1;
unsigned long blue1;
//転送元2から読み込んだピクセル情報
unsigned long readPixel2;
unsigned long red2;
unsigned long green2;
unsigned long blue2;
//合成結果を書き込むための演算結果
unsigned long writePixel;
unsigned long red3;
unsigned long green3;
unsigned long blue3;
//下方向へのループを設定
for (loopY = 0 ; loopY != imageSizeY ; loopY++) {
//各ラインの始点を指すポインタを取得し設定
readAddress1 = srcBaseAddress1 + srcRowBytes1 * loopY;
readAddress2 = srcBaseAddress2 + srcRowBytes2 * loopY;
writingAddress = dstBaseAddress + dstRowBytes * loopY;
//右方向に1ライン分のループを設定
for (loopX = 0 ; loopX != imageSizeX ; loopX++) {
//転送元1ポインタか ら4バイト(unsigned long型)ずつ読 み 込む
readPixel1 = *((unsigned long*)readAddress1)++;
//RGBそ れ ぞれ のレ ベ ルを抽 出
blue1 = readPixel1 & 0x000000ff;
readPixel1 = readPixel1 >> 8;
green1 = readPixel1 & 0x000000ff;
readPixel1 = readPixel1 >> 8;
red1 = readPixel1 & 0x000000ff;
//転送元2ポインタか ら4バイト(unsigned long型)ずつ読 み 込む
readPixel2 = *((unsigned long*)readAddress2)++;
//RGBそれぞれのレベルを抽出
blue2 = readPixel2 & 0x000000ff;
readPixel2 = readPixel2 >> 8;
green2 = readPixel2 & 0x000000ff;
readPixel2 = readPixel2 >> 8;
red2 = readPixel2 & 0x000000ff;
//各色の合成演算を行う(転送元1が(fadeLevel)%、転送元2が(100-fadeLevel)%)
red3 = red1 * fadeLevel / 100 + red2 * (100 - fadeLevel) / 100;
green3 = green1 * fadeLevel / 100 + green2 * (100 - fadeLevel) / 100;
blue3 =blue1 * fadeLevel / 100 + blue2 * (100 - fadeLevel) / 100;
//各色をunsigned long型のピクセルデータに戻す
writePixel = red3;
writePixel = writePixel << 8;
writePixel = writePixel | green3;
writePixel = writePixel << 8;
writePixel = writePixel | blue3;
//ピクセルデータを書き込む
*((unsigned long*)writingAddress)++ = writePixel;
}
}
}
//---------------------------------------------------------------------
//
// 指定したGWorldの内容に対して指定したトーンエフェクト
//
// 引数: Ptr dstBaseAddress 転送先ベースアドレス(ポインタ)
// long dstRowBytes 転送先ローバイト
// short imageSizeX イメージのサイズ横幅
// short imageSizeY イメージのサイズ縦幅
// short エフェクトの種類(0=なし)
// 戻り値: なし
//---------------------------------------------------------------------
void DoEffects(Ptr theBaseAddress,long theRowBytes,short imageSizeX,short imageSizeY,short effectNo)
{
Ptr readWriteAddress; //ピクセルデータの読み書き用のポインタ
short loopX,loopY; //forループ用
//読み込んだピクセル情報
unsigned long readWritePixel;
unsigned long red;
unsigned long green;
unsigned long blue;
unsigned long yValue;
//下方向へのループを設定
for (loopY = 0 ; loopY != imageSizeY ; loopY++) {
//各ラインの始点を指すポインタを取得し設定
readWriteAddress = theBaseAddress + theRowBytes * loopY;
//右方向に1ライン分のループを設定
for (loopX = 0 ; loopX != imageSizeX ; loopX++) {
//転送元1ポインタか ら4バイト(unsigned long型)ずつ読 み 込む
readWritePixel = *((unsigned long*)readWriteAddress);
//RGBそ れ ぞれ のレ ベ ルを抽 出
blue = readWritePixel & 0x000000ff;
readWritePixel = readWritePixel >> 8;
green = readWritePixel & 0x000000ff;
readWritePixel = readWritePixel >> 8;
red = readWritePixel & 0x000000ff;
switch (effectNo)
{
//モノクロ
case 1:
yValue = (red * 3 / 10) + (green * 6 / 10) + (blue * 1 / 10);
red = yValue;
green = yValue;
blue = yValue;
break;
//セピア
case 2:
yValue = (red * 3 / 10) + (green * 6 / 10) + (blue * 1 / 10);
red = yValue * 240 / 255;
green = yValue * 200 / 255;
blue = yValue * 145 / 255;
break;
//ネガポジ
case 3:
red = 255 - red;
green = 255 - green;
blue = 255 - blue;
break;
}
//各色をunsigned long型のピクセルデータに戻す
readWritePixel = red;
readWritePixel = readWritePixel << 8;
readWritePixel = readWritePixel | green;
readWritePixel = readWritePixel << 8;
readWritePixel = readWritePixel | blue;
//ピクセルデータを書き込む
*((unsigned long*)readWriteAddress)++ = readWritePixel;
}
}
}